/**************************************************************
 * configfile.h - for simple config handling.
 * Copyright (c) 2009  Qin Xiaoxue  <crs.chin@gmail.com>
 *
 * This file is  free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
**************************************************************/


#ifndef __CONFIGFILE_H
#define __CONFIGFILE_H

#include <stdio.h>
#include <glib.h>


/* the static default base directory which is
 * ~/PROG_NAME/PROG_VERSION/ if not specified in the API.  */
#ifndef PROG_NAME
#define PROG_NAME ".config/misc"
#endif

#ifndef PROG_VERSION
#define PROG_VERSION ""
#endif

struct __config_struct{
  GKeyFile *kfile;
  FILE *fp;
  const gchar *fname;
  const gchar *path;
  gboolean writeback;
  gboolean modified;
};

typedef struct __config_struct config_t;

/* 
 *load config from file @basedir/@category/@fname, if @create if TRUE,
 *create the file if not exist with default @default_data, the
 *function return NULL if failed to create config file ,or there is no
 *config file and @create is FALSE and @default_data is NULL, if @len
 *is 0, and @default_data is valid, it is calculate from @default_data
 */
config_t *load_config(const gchar *basedir, const gchar *category, 
					  const gchar *fname, const gchar *default_data,
					  gint len, gboolean create);

config_t *load_config_file(const gchar *file, const gchar *default_data, gint len, gboolean create);


/* 
 *read @key's value from config and set to @*val, set the @def to
 *@*val if @key don't exists and @def is not NULL, caller is
 *responsible to free @val's value, if @setback is true, set @def to
 *the config if the @key don't exist
 */
void     read_config(config_t *config, const gchar *group,
					 const gchar *key, gchar **val, 
					 const gchar *def, gboolean setback);

void     set_config(config_t *config, const gchar *group,
					const gchar *key, gchar *val);

/* 
 *read or set the config in the sepcified data type
 *AVAILABE TYPES:
 *      boolean, integer, double, string, value and comment
 *NOTE: string, value and comment are all of type char *.
 */
#define read_config_valtype(config, res, type, group, key)		\
  do{															\
	if(key)														\
	  if(group)													\
		res = g_key_file_get_##type(config->kfile, group,		\
									key, NULL);					\
	  else														\
		res = g_key_file_get_##type(config->kfile, "General",	\
									key, NULL);					\
  }while(0);


#define set_config_valtype(config, type, group, key, val)	\
  do{														\
	if(key)													\
	  if(group)												\
		g_key_file_set_##type(config->kfile, group,			\
							  key, val);					\
	  else													\
		g_key_file_set_##type(config->kfile, "General",		\
							  key, val);					\
  }while(0);

/* 
 *update the modified keys of config to the associated disk file
 */
void sync_config(config_t *config);

void    free_config(config_t *config);


#endif /* __CONFIGFILE_H */

